﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Twi.COMMON.Core
{
    /*
    * Copyright: ©2012 Twilight软件开发工作室版权所有
    * Author: xuzhihong
    * Create date: 2012-10-16
    * Description: TreeNodeStruct树结构，详细参考Twilight树结构设计
    * 
*/
    public class TwiTreeHelper<T> where T:TreeNodeStruct,new()
    {
        public static List<T> GetTreeData(DataTable dt, TreeNodeMapping mapping)
        {
            if (mapping == null) { mapping = new TreeNodeMapping(); }
            var nodes = new List<T>();
            if (dt.Rows.Count > 0)
            {
                string filterExpression = string.Format("{0} is null or {0}='{1}'", mapping.ParentIDField, mapping.RootParentIDValue);
                if (dt.Rows[0][mapping.ParentIDField].GetType() != typeof(string))
                {
                    filterExpression = string.Format("Convert({0},'System.String') is null or Convert({0},'System.String')='{1}'", mapping.ParentIDField, mapping.RootParentIDValue);
                }
;               foreach (var row in dt.Select(filterExpression, mapping.SortField + " " + mapping.SortDirection))
                {
                    var node = CreateNode(row, mapping);
                    nodes.Add(node);
                    FillChildren(row, node, dt, mapping);
                    node.leaf = node.children.Count == 0;
                }
            }
            return nodes;
        }

        static T CreateNode(DataRow row,TreeNodeMapping mapping)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            foreach (DataColumn dc in row.Table.Columns)
            {
                dict.Add(dc.ColumnName, row[dc].ToString());
            }
            var cols = row.Table.Columns;
            return new T
            {
                id = cols.Contains(mapping.IDField)?""+row[mapping.IDField]:"",
                text = cols.Contains(mapping.TextField) ? "" + row[mapping.TextField] : "",
                sort = cols.Contains(mapping.SortField) ? "" + row[mapping.SortField] : "",
                remark = cols.Contains(mapping.RemarkField) ? "" + row[mapping.RemarkField] : "",
                level = cols.Contains(mapping.LevelField) ? "" + row[mapping.LevelField] : "",
                value = cols.Contains(mapping.ValueField) ? "" + row[mapping.ValueField] : "",
                code = cols.Contains(mapping.CodeField) ? "" + row[mapping.CodeField] : "",
                dict = dict
            };
        }

        static void FillChildren(DataRow parentRow, T parentNode, DataTable dt,TreeNodeMapping mapping)
        {
            string filterExpression =string.Format("{0}='{1}'", mapping.ParentIDField, parentRow[mapping.IDField]);
            if (dt.Rows[0][mapping.ParentIDField].GetType() != typeof(string))
            {
                filterExpression = string.Format("Convert({0},'System.String')='{1}'", mapping.ParentIDField, parentRow[mapping.IDField]);
            }
            foreach (var row in dt.Select(filterExpression, mapping.SortField + " " + mapping.SortDirection))
            {
                var node = CreateNode(row,mapping);
                parentNode.children.Add(node);
                FillChildren(row, node, dt, mapping);
                node.leaf = node.children.Count == 0;
            }
        }
    }

    /// <summary>
    /// 树节点信息
    /// </summary>
    public class TreeNodeStruct
    {
        public TreeNodeStruct()
        {
            this.children = new List<TreeNodeStruct>();
            this.dict = new Dictionary<string, object>();
        }
        /// <summary>
        /// 树节点id
        /// </summary>
        public string id
        {
            get;set;
        }
        /// <summary>
        /// 树节点显示文本
        /// </summary>
        public string text
        {
            get;
            set;
        }
        /// <summary>
        /// 对应TreeMapping.Value
        /// </summary>
        public string value
        {
            get;
            set;
        }
        /// <summary>
        /// 是否为叶子节点
        /// </summary>
        public bool leaf
        {
            get;set;
        }
        /// <summary>
        /// 排序
        /// </summary>
        public string sort
        {
            get;set;
        }        
        /// <summary>
        /// 深度  根节点为0
        /// </summary>
        public string level
        {
            get;set;
        }
        /// <summary>
        /// 父节点
        /// </summary>
        public string parentID
        {
            get;
            set;
        }
        /// <summary>
        /// 编码 01、0101、0102
        /// </summary>
        public string code
        {
            get;
            set;
        }
        /// <summary>
        /// 备注/说明
        /// </summary>
        public string remark
        {
            get;
            set;
        }

        /// <summary>
        /// 节点图标
        /// </summary>
        public string iconCls
        {
            get;
            set;
        }
        /// <summary>
        /// 节点样式
        /// </summary>
        public string cls
        {
            get;
            set;
        }
        /// <summary>
        /// 代替树节点的checked属性 （checked为C#关键字）
        /// </summary>
        public bool isChecked
        {
            get;
            set;
        }

        /// <summary>
        /// 子节点集合
        /// </summary>
        public List<TreeNodeStruct> children
        {
            get;
            set;
        }
        /// <summary>
        /// 所有字段信息记录/其他额外字段记录
        /// </summary>
        public Dictionary<string, object> dict
        {
            get;
            set;
        }
    }

    /// <summary>
    /// 树节点字段与表字段映射关系
    /// </summary>
    public class TreeNodeMapping
    {
        public TreeNodeMapping()
        {
            IDField ="FID";
            TextField = "FName";
            ValueField = "FValue";
            ParentIDField = "FParentID";
            SortField = "FSort";
            SortDirection = "ASC";
            LevelField = "FLevel";
            CodeField = "FCode";
            RemarkField = "FRemark";
            RootParentIDValue = "";  
        }
        /// <summary>
        /// FID
        /// </summary>
        public string IDField
        {
            get;
            set;
        }


        /// <summary>
        /// FNAME
        /// </summary>
        public string TextField
        {
            get;
            set;
        }
        /// <summary>
        /// FValue
        /// </summary>
        public string ValueField
        {
            get;
            set;
        }
        /// <summary>
        /// FParentID
        /// </summary>
        public string ParentIDField
        {
            get;
            set;
        }
        /// <summary>
        /// FSort
        /// </summary>
        public string SortField
        {
            get;
            set;
        }
        /// <summary>
        /// ASC/DESC(Defaults:ASC)
        /// </summary>
        public string SortDirection
        {
            get;
            set;
        }
        /// <summary>
        /// FLevel
        /// </summary>
        public string LevelField
        {
           get;
           set;
        }
        /// <summary>
        /// FCode
        /// </summary>
        public string CodeField
        {
            get;
            set;
        }
        /// <summary>
        /// FRemark
        /// </summary>
        public string RemarkField
        {
            get;
            set;
        }
        /// <summary>
        /// 根节点的值（默认：空字符串"",系统会自动加上 is null ）
        /// </summary>
        public string RootParentIDValue
        {
            get;
            set;
        }
        
    }

    /// <summary>
    /// easy ui 需要的树结构
    /// </summary>
    public class EasyUITreeNodeStruct : TreeNodeStruct
    {  
        public Dictionary<string,object> attributes
        {
            get { return dict; }
        }        
    }
}
